<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-us" lang="en-us">
<head>
  <link href="//gmpg.org/xfn/11" rel="profile">
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta name="generator" content="Hugo 0.68.3" />

  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>Django 使用现有数据库生成 models &middot; 我的博客</title>

  
  <link type="text/css" rel="stylesheet" href="/my_technology_blog/css/print.css" media="print">
  <link type="text/css" rel="stylesheet" href="/my_technology_blog/css/poole.css">
  <link type="text/css" rel="stylesheet" href="/my_technology_blog/css/syntax.css">
  <link type="text/css" rel="stylesheet" href="/my_technology_blog/css/hyde.css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Abril+Fatface|PT+Sans:400,400i,700">


  
  <link rel="apple-touch-icon-precomposed" sizes="144x144" href="/apple-touch-icon-144-precomposed.png">
  <link rel="shortcut icon" href="/favicon.png">

  
  
</head>

  <body class="theme-base-0b ">
  <aside class="sidebar">
  <div class="container sidebar-sticky">
    <div class="sidebar-about">
      <a href="/my_technology_blog/"><h1>我的博客</h1></a>
      <p class="lead">
       杨博的博客 
      </p>
    </div>

    <nav>
      <ul class="sidebar-nav">
        <li><a href="/my_technology_blog/">Home</a> </li>
        
      </ul>
    </nav>

    <p>&copy; 2021. All rights reserved. </p>
  </div>
</aside>

    <main class="content container">
    <div class="post">
  <h1>Django 使用现有数据库生成 models</h1>
  <time datetime=2020-09-07T18:47:21&#43;0800 class="post-date">Mon, Sep 7, 2020</time>
  <p>通常，我们是先建立 Django 服务，然后通过 Django 的 models 生成数据库。然而，有些时候我们需要反向操作，即从现有数据库生成 Django 的 models。比如，我们需要针对当前数据库，使用 Django 制作 REST 的接口。</p>
<h2 id="1-django-配置数据库连接参数">1 Django 配置数据库连接参数</h2>
<p>新建 Djano项目、app（假设名叫 blogapp）。在 settings.py 中设置数据库的连接参数，参照 <a href="https://www.jianshu.com/p/13b77e9641d1">Django 与 MySQL 数据库的连接</a>。</p>
<h2 id="2-根据数据库生成-models">2 根据数据库生成 models</h2>
<p>首先，需要用 <code>inspectdb</code> 来生成 <code>models.py</code>，主要的命令是</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python">python manage<span style="color:#f92672">.</span>py inspectdb
</code></pre></div><p>假设指定 models，比如 blogapp 下面的 models</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python">python manage<span style="color:#f92672">.</span>py inspectdb <span style="color:#f92672">&gt;</span> blogapp<span style="color:#f92672">/</span>models<span style="color:#f92672">.</span>py
</code></pre></div><h2 id="3-models-中的调整-managed--true">3 models 中的调整 <code>managed = True</code></h2>
<p>对于自己需要的 models，如果需要以后进行 CRUD 增删查改操作，需要在 Meta 中设置 <code>managed = True</code>。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python"><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">PostsPost</span>(models<span style="color:#f92672">.</span>Model):
    title <span style="color:#f92672">=</span> models<span style="color:#f92672">.</span>CharField(max_length<span style="color:#f92672">=</span><span style="color:#ae81ff">150</span>)
    content <span style="color:#f92672">=</span> models<span style="color:#f92672">.</span>TextField()
    timestamp <span style="color:#f92672">=</span> models<span style="color:#f92672">.</span>DateTimeField()
    updated <span style="color:#f92672">=</span> models<span style="color:#f92672">.</span>DateTimeField()

    <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Meta</span>:
        managed <span style="color:#f92672">=</span> True
        db_table <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;posts_post&#39;</span>
</code></pre></div><h2 id="4-migrate-时使用---fake-initial">4 migrate 时，使用 <code>--fake-initial</code></h2>
<p>首次数据迁移 migrate 时，需要使用 <code>--fake-initial</code> 参数，因为数据库已经存在，不带 <code>--fake</code> 会报错且迁移不成功。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python"><span style="color:#960050;background-color:#1e0010">$</span> python manage<span style="color:#f92672">.</span>py makemigrations
<span style="color:#960050;background-color:#1e0010">$</span> python manage<span style="color:#f92672">.</span>py migrate <span style="color:#f92672">--</span>fake<span style="color:#f92672">-</span>initial
</code></pre></div><h2 id="5-测试效果">5 测试效果</h2>
<p>在 blog/admin.py 中把 models 注册进去。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python"><span style="color:#f92672">from</span> django.contrib <span style="color:#f92672">import</span> admin
<span style="color:#f92672">from</span> .models <span style="color:#f92672">import</span> PostsPost

admin<span style="color:#f92672">.</span>site<span style="color:#f92672">.</span>register(PostsPost)
</code></pre></div><p>使用 admin 进行增删查改，并且在 MySQL 中确认数据库操作成功。</p>
<h2 id="6-使用了---fake-之后需要修改-models">6 使用了 <code>--fake</code> 之后，需要修改 models</h2>
<p>如果不再是 <code>—fake</code> 而需要真实改动数据库结构，需要</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python">python manage<span style="color:#f92672">.</span>py migrate <span style="color:#f92672">--</span>fake core <span style="color:#ae81ff">0003</span>
python manage<span style="color:#f92672">.</span>py migrate core
</code></pre></div><p><a href="https://link.jianshu.com?t=https://stackoverflow.com/questions/30626886/how-to-redo-a-migration-on-django-1-8-after-using-fake">How to redo a migration on django 1.8 after using &ndash;fake</a></p>
<h2 id="备注">备注：</h2>
<p>最后需要注意：Django 的整体全局 migrate，会因为出现没找到变化的情况。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python">python manage<span style="color:#f92672">.</span>py migrate
</code></pre></div><p>建议还是制定 app 进行 migrate</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python">python manage<span style="color:#f92672">.</span>py migrate your_app
</code></pre></div><h2 id="参考">参考</h2>
<p>官方文档最新指南：</p>
<p><a href="https://link.jianshu.com?t=https://docs.djangoproject.com/en/1.11/howto/legacy-databases/">官方英文文档：Auto-generate the models</a></p>
<p><a href="https://link.jianshu.com?t=https://docs.djangoproject.com/en/1.11/ref/django-admin/#django-admin-inspectdb">官方英文文档：inspectdb</a></p>
<p><a href="https://link.jianshu.com?t=https://docs.djangoproject.com/en/1.8/topics/migrations/#adding-migrations-to-apps">官方英文文档：migrate —fake-initial</a></p>
<p><a href="https://link.jianshu.com?t=https://www.rddoc.com/doc/Django-1.10.5/howto/legacy-databases/">官方文档中文翻译：将Django与旧数据库集成</a></p>
<p>中文的介绍：</p>
<p><a href="https://link.jianshu.com?t=https://my.oschina.net/1123581321/blog/213003">已有的数据库集成django orm (Database to Models)</a></p>
<p><a href="https://link.jianshu.com?t=http://www.yihaomen.com/article/python/244.htm">从数据库反向生成django的models</a></p>
<p><a href="https://link.jianshu.com?t=http://www.eoeandroid.com/thread-923932-1-1.html">在已有数据库上如何创建Django项目</a></p>
<p><a href="https://link.jianshu.com?t=http://blog.csdn.net/nyist327/article/details/50437291">Django根据现有数据库建立model</a></p>
<p>Django Book 一些清理生成的 Models 的建议</p>
<p><a href="https://link.jianshu.com?t=http://djangobook.py3k.cn/2.0/chapter18/">集成已有的数据库和应用</a></p>
<p>关于Django migrate 的两个参数<code>—fake-initial</code> 与 <code>—fake</code>：</p>
<p><a href="https://link.jianshu.com?t=http://ju.outofmemory.cn/entry/169326">django migration的使用</a></p>
<p><a href="https://link.jianshu.com?t=https://stackoverflow.com/questions/42695629/fake-initial-vs-fake-in-django-migration">&ndash;fake-initial vs &ndash;fake in Django migration?</a></p>

</div>


    </main>

    
  </body>
</html>
